home *** CD-ROM | disk | FTP | other *** search
- /*
- * IPERSTOR.CPP
- * Polyline Component Object Chapter 6
- *
- * Implementation of the IPersistStorage interface that we expose on the
- * Polyline object.
- *
- * Copyright (c)1993 Microsoft Corporation, All Rights Reserved
- *
- * Kraig Brockschmidt, Software Design Engineer
- * Microsoft Systems Developer Relations
- *
- * Internet : kraigb@microsoft.com
- * Compuserve: >INTERNET:kraigb@microsoft.com
- */
-
-
- #include "polyline.h"
-
-
- /*
- * CImpIPersistStorage:CImpIPersistStorage
- * CImpIPersistStorage::~CImpIPersistStorage
- *
- * Constructor Parameters:
- * pObj LPVOID pointing to the object we live in.
- * punkOuter LPUNKNOWN of the controlling unknown.
- */
-
- CImpIPersistStorage::CImpIPersistStorage(LPVOID pObj, LPUNKNOWN punkOuter)
- {
- m_cRef=0;
- m_pObj=pObj;
- m_punkOuter=punkOuter;
- return;
- }
-
-
- CImpIPersistStorage::~CImpIPersistStorage(void)
- {
- return;
- }
-
-
-
-
- /*
- * CImpIPersistStorage::QueryInterface
- * CImpIPersistStorage::AddRef
- * CImpIPersistStorage::Release
- *
- * Purpose:
- * Standard set of IUnknown members for this interface
- */
-
- STDMETHODIMP CImpIPersistStorage::QueryInterface(REFIID riid, LPVOID FAR *ppv)
- {
- return m_punkOuter->QueryInterface(riid, ppv);
- }
-
- STDMETHODIMP_(ULONG) CImpIPersistStorage::AddRef(void)
- {
- ++m_cRef;
- return m_punkOuter->AddRef();
- }
-
- STDMETHODIMP_(ULONG) CImpIPersistStorage::Release(void)
- {
- --m_cRef;
- return m_punkOuter->Release();
- }
-
-
-
-
-
- /*
- * CImpIPersistStorage::GetClassID
- *
- * Purpose:
- * Returns the CLSID of the object represented by this interface.
- *
- * Parameters:
- * pClsID LPCLSID in which to store our CLSID.
- *
- * Return Value:
- * HRESULT NOERROR on success, error code otherwise.
- */
-
- STDMETHODIMP CImpIPersistStorage::GetClassID(LPCLSID pClsID)
- {
- LPCPolyline pObj=(LPCPolyline)m_pObj;
-
- *pClsID=pObj->m_clsID;
- return NOERROR;
- }
-
-
-
-
-
- /*
- * CImpIPersistStorage::IsDirty
- *
- * Purpose:
- * Tells the caller if we have made changes to this object since
- * it was loaded or initialized new.
- *
- * Parameters:
- * None
- *
- * Return Value:
- * HRESULT Contains S_OK if we ARE dirty, S_FALSE if NOT dirty,
- * that is, "Yes I AM dirty, or NO, I'm clean."
- */
-
- STDMETHODIMP CImpIPersistStorage::IsDirty(void)
- {
- LPCPolyline pObj=(LPCPolyline)m_pObj;
-
- return ResultFromScode(pObj->m_fDirty ? S_OK : S_FALSE);
- }
-
-
-
-
-
-
-
- /*
- * CImpIPersistStorage::InitNew
- *
- * Purpose:
- * Provides the object with the IStorage they can hold on to while
- * they are running. Here we can initialize the structure of the
- * storage and AddRef it for incremental access. This function will
- * only be called once in the object's lifetime in lieu of ::Load.
- *
- * Parameters:
- * pIStorage LPSTORAGE for the object.
- *
- * Return Value:
- * HRESULT NOERROR on success, error code otherwise.
- */
-
- STDMETHODIMP CImpIPersistStorage::InitNew(LPSTORAGE pIStorage)
- {
- //Nothing to do. We don't need a storage outside ::Load and ::Save.
- return NOERROR;
- }
-
-
-
-
-
- /*
- * CImpIPersistStorage::Load
- *
- * Purpose:
- * Instructs the object to load itself from a previously saved IStorage
- * that was handled by ::Save in another object lifetime. This function
- * will only be called once in the object's lifetime in lieu of ::InitNew.
- * The object may hold on to pIStorage here for incremental access.
- *
- * Parameters:
- * pIStorage LPSTORAGE from which to load.
- *
- * Return Value:
- * HRESULT NOERROR on success, error code otherwise.
- */
-
- STDMETHODIMP CImpIPersistStorage::Load(LPSTORAGE pIStorage)
- {
- LPCPolyline pObj=(LPCPolyline)m_pObj;
- POLYLINEDATA pl;
- ULONG cb;
- LPSTREAM pIStream;
- HRESULT hr;
-
- if (NULL==pIStorage)
- return ResultFromScode(STG_E_INVALIDPOINTER);
-
- //We don't check ClassStg to remain compatible with other chatpers.
-
- //Open the CONTENTS stream
- hr=pIStorage->OpenStream("CONTENTS", 0, STGM_DIRECT | STGM_READ
- | STGM_SHARE_EXCLUSIVE, 0, &pIStream);
-
- if (FAILED(hr))
- return ResultFromScode(STG_E_READFAULT);
-
- //Read all the data into the POLYLINEDATA structure.
- hr=pIStream->Read((LPVOID)&pl, CBPOLYLINEDATA, &cb);
- pIStream->Release();
-
- if (CBPOLYLINEDATA!=cb)
- return ResultFromScode(STG_E_READFAULT);
-
- //CHAPTER6MOD
- //DataSet now internal on CPolyline
- pObj->DataSet(&pl, TRUE, TRUE);
- //End CHAPTER6MOD
- return NOERROR;
- }
-
-
-
-
-
- /*
- * CImpIPersistStorage::Save
- *
- * Purpose:
- * Saves the data for this object to an IStorage which may
- * or may not be the same as the one previously passed to
- * ::Load, indicated with fSameAsLoad.
- *
- * Parameters:
- * pIStorage LPSTORAGE in which to save our data.
- * fSameAsLoad BOOL indicating if this is the same pIStorage
- * that was passed to ::Load. If it was, then
- * objects that built up a structure in that storage
- * do not have to regenerate the entire thing.
- *
- * Return Value:
- * HRESULT NOERROR on success, error code otherwise.
- */
-
- STDMETHODIMP CImpIPersistStorage::Save(LPSTORAGE pIStorage, BOOL fSameAsLoad)
- {
- LPCPolyline pObj=(LPCPolyline)m_pObj;
- POLYLINEDATA pl;
- ULONG cb;
- LPSTREAM pIStream;
- HRESULT hr;
-
- if (NULL==pIStorage)
- return ResultFromScode(STG_E_INVALIDPOINTER);
-
- /*
- * fSameAsLoad is not important to us since we always rewrite
- * an entire stream as well as the identification tags for this
- * object. Note that we don't bother to check the ClassStg
- * above in ::Load to remain compatible with other revisions
- * of Polyline in other chapters.
- */
-
- WriteClassStg(pIStorage, pObj->m_clsID);
- WriteFmtUserTypeStg(pIStorage, pObj->m_cf, (*pObj->m_pST)[IDS_USERTYPE]);
-
- hr=pIStorage->CreateStream("CONTENTS", STGM_DIRECT | STGM_CREATE
- | STGM_WRITE | STGM_SHARE_EXCLUSIVE, 0, 0, &pIStream);
-
- if (FAILED(hr))
- return ResultFromScode(STG_E_WRITEFAULT);
-
- //CHAPTER6MOD
- //DataGet now internal on CPolyline
- pObj->DataGet(&pl);
- //End CHAPTER6MOD
-
- hr=pIStream->Write((LPVOID)&pl, CBPOLYLINEDATA, &cb);
- pIStream->Release();
-
- return (SUCCEEDED(hr) && CBPOLYLINEDATA==cb) ?
- NOERROR : ResultFromScode(STG_E_WRITEFAULT);
- }
-
-
-
-
-
-
-
-
- /*
- * CImpIPersistStorage::SaveCompleted
- *
- * Purpose:
- * Notifies the object that the storage in pIStorage has been completely
- * saved now. This is called when the user of this object wants to
- * save us in a completely new storage, and if we normally hang on to
- * the storage we have to reinitialize ourselves here for this new one
- * that is now complete.
- *
- * Parameters:
- * pIStorage LPSTORAGE of the new storage in which we now live.
- *
- * Return Value:
- * HRESULT NOERROR on success, error code otherwise.
- */
-
- STDMETHODIMP CImpIPersistStorage::SaveCompleted(LPSTORAGE pIStorage)
- {
- /*
- * We have nothing to do here since we do everything in ::Load and
- * ::Save. For most objects than handle saves this way, they need
- * no code here. Other objects must release their current storage
- * here and begin using the new one in pIStorage.
- */
-
- return NOERROR;
- }
-
-
-
-
-
- /*
- * CImpIPersistStorage::HandsOffStorage
- *
- * Purpose:
- * Instructs the object that another agent is interested in having total
- * access to the storage we might be hanging on to from ::InitNew or
- * ::SaveCompleted. In this case we must release our hold and await
- * another call to ::SaveCompleted before we have a hold again.
- *
- * Situations where this might happen arise in compound document scenarios
- * where this object might be in-place active but the application wants
- * to rename and commit the root storage. Therefore we are asked to
- * close our hold, let the container party on the storage, then call us
- * again later to tell us the new storage we can hold.
- *
- * Parameters:
- * None
- *
- * Return Value:
- * HRESULT NOERROR on success, error code otherwise.
- */
-
- STDMETHODIMP CImpIPersistStorage::HandsOffStorage(void)
- {
- //Nothing for us to do
- return NOERROR;
- }
-